#ifndef PROT_H
#define PROT_H

#include "types.h"


// 1gb pages test window
#define GFP_ORDER_1GB 10
#define TEST_WINDOW_1GB ( (1 << GFP_ORDER_1GB) * 4 * 1024 )


// page not specified for address commands
#define PAGE_UNDEFINED ((u32)-1)


#pragma pack(push, 1)

struct interrupt_info {
  u8 int_num;
  u8 interrupt : 1, has_error_code : 1, unused0 : 6;
  u16 count;
  u32 error_code;
};
CHECK_STRUCT_SIZE(interrupt_info, 8);

enum {
  CMD_READ,
  CMD_WRITE,
  CMD_RUN,
  CMD_FLAGS,
  CMD_MAP,
  CMD_INV,
  CMD_END,
  CMD_FLUSH,
  CMD_NOOP
};
  
enum {
  RESULT_OK,
  RESULT_ERROR
};

enum {
  PM_32,
  PM_PAE,
  PM_64
};

struct test_command {
  struct {
    u32 has_result: 1;
    u32 cmd: 31;
  };
  
  u32 page; // for Map/Flags - page which is page structure to change
	    // for data saving with address commands
  
  union {
    vaddr_t vaddr; // for address commands (read at vaddr, write to addr, etc)
    u64 flags; // for Flags
    u64 addr_mask; // for Map
  };
  
  union {
    u32 page2; // for Map
    u64 uflags; // for Flags
  };
  
  u32 pos; // for Map/Flags - entry position in page structure
};
CHECK_STRUCT_SIZE(test_command, 28);


struct test_header {
  u32 n_pages;
  u32 n_commands;
};
CHECK_STRUCT_SIZE(test_header, 8);


#pragma pack(pop)

#endif /* PROT_H */